#pragma once

namespace FormatPrint
{
#pragma warning(push)
#pragma warning(disable:4996 )
	template<class Printer>
	class CFormatPrint
	{
	public:
		static const int MAX_BUF_LEN=1024;
		static const int MAX_FLUSH_LEN=1000;
		CFormatPrint(size_t nMaxPrint=-1)
			:m_nMaxPrint(nMaxPrint)
			,m_nPrinted(0)
		{
			m_pPrintBuf=m_Buf.Allocate((size_t)MAX_BUF_LEN);
			memset(m_pPrintBuf,0,MAX_BUF_LEN);
		}

		void Print(const char* buf,int len)
		{			
			int j=0;
			int plus=0;
			int i=0;
			for(;i<len&&m_nPrinted<m_nMaxPrint;i++)
			{
				plus=0;
				if(buf[i]<0)
				{
					//j+=sprintf(pPrintBuf+j,"/u%04d",pRecvBuf[i]);
					plus+=sprintf(m_pPrintBuf+j,"/u%04d",buf[i]);
				}
				else if(isprint(buf[i]))
				{					
					m_pPrintBuf[j]=buf[i];
					plus++;					
				}
				else if(iscntrl(buf[i])&&isspace(buf[i]))
				{
					switch(buf[i])
					{
					case '\r':
						{
							strcat(m_pPrintBuf+j,"\\r");
							plus+=2;
						}
						break;
					case '\n':
						{
							strcat(m_pPrintBuf+j,"\\n\n");
							plus+=3;
						}
						break;
					case '\t':
						{
							strcat(m_pPrintBuf+j,"\\t->->");
							plus+=6;
						}
						break;
					case ' ':
						{
							strcat(m_pPrintBuf+j,"[SP]");
							plus+=4;
						}
						break;
					}
				}
				else
				{
					plus+=sprintf(m_pPrintBuf+j,"/u%04d",buf[i]);					
				}
// 				if(memcmp(pRecvBuf+i-4,"\r\n\r\n",4)==0)
// 					break;
				j+=plus;
				m_nPrinted+=plus;
				if(j>=MAX_FLUSH_LEN||m_nPrinted>=m_nMaxPrint)
				{
					Printer::print(m_pPrintBuf,j);
					memset(m_pPrintBuf,0,MAX_BUF_LEN);
					j=0;
				}
			}
			if(j>0)
				Printer::print(m_pPrintBuf,j);
			memset(m_pPrintBuf,0,MAX_BUF_LEN);
		}
	private:
		const size_t m_nMaxPrint;
		size_t m_nPrinted;
		CTempBuffer<CHAR> m_Buf;
		CHAR *m_pPrintBuf;
	};
#pragma warning(pop)
}